﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

// Call this when a new game is started.
public class NewGame : MonoBehaviour {

	// The maze to generate
	public Maze maze;
	// The instance of the maze
	private Maze instance;
	// The player character.
	public PlayerControl player;
	// The instance of the player
	private PlayerControl playerInstance;
	// The enemy character
	public Enemy enemy;
	// The instance of the enemy.
	private Enemy enemyInstance;
	// The index of the player
	private int playerIndex;
	// The timer
	public Timer timer;
	// The timer instance
	private Timer timerInstance;

	// Use this for initialization
	void Start () {
		BeginGame();
	}
	
	// Update is called once per frame
	void Update () {
		if(Input.GetKeyDown(KeyCode.Space)) {
			RestartGame ();
		}

		if(instance != null && instance.doneGenerating && playerInstance == null && enemyInstance == null) {
			playerInstance = Instantiate (player) as PlayerControl;
			IntVector2 playerPos = getPlayerPos();
			playerInstance.gridPos = playerPos;
			playerInstance.transform.localPosition = new Vector3(playerPos.x - instance.size.x * 0.5f + 0.6f, playerPos.y - instance.size.y * 0.5f + 0.4f, 0f);
			enemyInstance = Instantiate (enemy) as Enemy;
			IntVector2 enemyPos = getPlayerPosOpposite();
			enemyInstance.transform.localPosition = new Vector3(enemyPos.x - instance.size.x * 0.5f + 0.5f, enemyPos.y - instance.size.y * 0.5f + 0.5f, 0f);
			for(int i = 0; i < instance.size.x; i++) {
				for(int j = 0; j < instance.size.y; j++) {
					MazeCell cell = instance.cells[i, j];
					if(cell.coordinates.Equals(enemyPos)) {
						enemyInstance.currCell = instance.cells[i,j];
						break;
					}
				}
			}
			timerInstance = Instantiate(timer) as Timer;
			timerInstance.transform.localPosition = new Vector3(10, 0, 0);
		}
		if (instance != null && instance.doneGenerating && enemyInstance != null) {
			for(int i = 0; i < instance.size.x; i++) {
				for(int j = 0; j < instance.size.y; j++) {
					if(instance.cells[i,j].hasEnemy) {
						enemyInstance.currCell = instance.cells[i,j];
						break;
					}
				}
			}
		}

	}

	// Generate the GUI
	void OnGUI() {
		if (timerInstance != null && timerInstance.gameOver) {
			GUIStyle style = new GUIStyle();
			style.fontSize += 40;
			style.normal.textColor = Color.red;
			if(instance.getPlayerScore() > instance.getEnemyScore()) {
				GUI.Label(new Rect(550, 15, 100, 60), "You Win!", style);
			}
			else if(instance.getPlayerScore() < instance.getEnemyScore()) {
				GUI.Label(new Rect(550, 15, 100, 60), "You Lose!", style);
			}
			else{
				GUI.Label(new Rect(550, 15, 100, 60), "Tie Game!", style);
			}
			GUI.Label(new Rect(450, 50, 100, 60), "Press space to play again", style);
			playerInstance.canMove = false;
			enemyInstance.canMove = false;
		}
	}

	// Starts the game
	private void BeginGame() {
		instance = Instantiate(maze) as Maze;
		StartCoroutine(instance.Generate());
	}

	// Check if the given edge is a passage
	public bool checkPassage (MazeCellEdge edge) {
		return (edge.GetType () == typeof(MazePassage));
	}

	// Stop the current instance, clear the board and restart it.
	private void RestartGame() {
		StopAllCoroutines();
		Destroy(enemyInstance.gameObject);
		Destroy(playerInstance.gameObject);
		Destroy(instance.gameObject);
		Destroy (timerInstance.gameObject);
		BeginGame();
	}

	// Return the player's current position.
	public IntVector2 getPlayerPos() {
		IntVector2[] playerPos = {
			new IntVector2(0, 0),
			new IntVector2(0, instance.size.y - 1),
			new IntVector2(instance.size.x - 1, 0),
			new IntVector2(instance.size.x - 1, instance.size.y - 1)
		};
		playerIndex = Random.Range(0, 4);
		return playerPos[playerIndex];
	}

	// Get the position opposite of the player
	public IntVector2 getPlayerPosOpposite() {
		IntVector2[] playerPosOpposite = {
			new IntVector2(instance.size.x - 1, instance.size.y - 1),
			new IntVector2(instance.size.x - 1, 0),
			new IntVector2(0, instance.size.y - 1),
			new IntVector2(0, 0)
		};
		return playerPosOpposite[playerIndex];
	}

	// Get the position adjacent to the player.
	public IntVector2 getPlayerPosAdjacent() {
		IntVector2[] playerPosAdjacent = {
			new IntVector2(instance.size.x - 1, 0),
			new IntVector2(instance.size.x - 1, instance.size.y - 1),
			new IntVector2(0, 0),
			new IntVector2(0, instance.size.y - 1)
		};
		return playerPosAdjacent[playerIndex];
	}

	// Get the other position adjacent to the player.
	public IntVector2 getPlayerPosAdjacentOther() {
		IntVector2[] playerPosAdjacentOther = {
			new IntVector2(0, instance.size.y - 1),
			new IntVector2(0, 0),
			new IntVector2(instance.size.x - 1, instance.size.y - 1),
			new IntVector2(instance.size.x - 1, 0)
		};
		return playerPosAdjacentOther[playerIndex];
	}

}
